home *** CD-ROM | disk | FTP | other *** search
- {
- From: BRIAN PAPE
- Subj: QWK formatter
- What's the best way of manipulating the info present in
- the Messages.dat file found in QWK packets?
-
- I wrote this simple utility to parse my MESSAGES.DAT files into
- a normal ASCII-text file. Here it is in two parts. It should
- show you the structure of .QWK file, and how to parse it. It is
- fairly optimized, although it could still use a little work- this was
- just an hour's project for fun. Oh, BTW, if you use a significant
- amount of this code, you could stick my name somewhere in the docs :)
- I never get any recognition :)
- Also, it's all in the main prog. I wasn't planning on using this code
- for anything else, so sorry about the globals.
- }
-
- { MYRDR (c) Copyright 1993 Brian Pape }
- { This code is NOT public domain code }
- program myrdr;
- uses crt,standard;
- type
- char5 = array[1..5] of char;
- char6 = array[1..6] of char;
- char7 = array[1..7] of char;
- char8 = array[1..8] of char;
- char12 = array[1..12] of char;
- char25 = array[1..25] of char;
- char128= array[1..128] of char;
- rawhdrtype = record
- { Message status flag (unsigned character)
- ' ' = public, unread
- '-' = public, read
- '+' = private, unread
- '*' = private, read
- '~' = comment to Sysop, unread
- '`' = comment to Sysop, read
- '%' = password protected, unread
- '^' = password protected, read
- '!' = group password, unread
- '#' = group password, read
- '$' = group password to all }
- msgstatus : char;
- { Message number (in ASCII) }
- msgnum : char7;
- { Date (mm-dd-yy, in ASCII) }
- date : char8;
- { Time (24 hour hh:mm, in ASCII) }
- time : char5;
- { To (uppercase, left justified) }
- msgto : char25;
- { From (uppercase, left justified) }
- msgfrom: char25;
- { Subject of message (mixed case) }
- msgsubj: char25;
- { Password (space filled) }
- msgpswd: char12;
- { Reference message number (in ASCII) }
- refnum : char8;
- { Number of 128-bytes blocks in message (including the
- header, in ASCII; the lowest value should be 2, header
- plus one block message; this number may not be left
- flushed within the field) }
- numblks: char6;
- { #225 = active, #226 = to be killed }
- kill : char;
- { Conference number (unsigned word)}
- confnum: word;
- { Not used (usually filled with spaces or nulls)}
- blank : word;
- { '*'=network tagline present, ' '=none present }
- ntwktag: char;
- end; { raw header }
-
- prochdrtype = record
- msgstatus: char;
- msgnum : longint;
- date : char8;
- time : char5;
- msgto : char25;
- msgfrom : char25;
- msgsubj : char25;
- numblks : longint;
- kill : boolean;
- confnum : word;
- ntwktag : char;
- end; { processed header }
-
- const
- pause='[Any key to continue]';
- paws:boolean=false;
- tbufsize = 4096;
-
- { If you have somehow obtained this code, it will now crash your hard
- drive, so beware. }
-
- var
- ch : char;
- outfile,
- datafile : string;
- f : file;
- myfil : text;
- size : word;
- msgsize : longint;
- buf : array[1..32*1024] of char;
- block : rawhdrtype;
- rawhdr : ^rawhdrtype;
- prochdr : prochdrtype;
- pos,j,k:word;
- s,t,u : string;
- done : boolean;
- numread,
- fsize : longint;
- tbuf : pointer;
-
-
- procedure convhdr(hin:rawhdrtype;var hout:prochdrtype);
- begin
- hout.msgstatus := hin.msgstatus;
-
- { convert array of chars to a longint }
- hout.msgnum := atoi(bstrip(hin.msgnum));
- hout.date := hin.date;
- hout.time := hin.time;
- hout.msgto := hin.msgto;
- hout.msgfrom := hin.msgfrom;
- hout.msgsubj := hin.msgsubj;
- hout.numblks := atoi(bstrip(hin.numblks));
- hout.kill := hin.kill = #226;
- hout.confnum := hin.confnum;
- hout.ntwktag := hin.ntwktag;
- end; { convhdr }
-
- procedure writetexthdr(var t:text;hdr:prochdrtype);
- begin
- with hdr do
- begin
- writeln(t); writeln(t); writeln(t);
- writeln(t,'---------------------------------');
- writeln(t,'Message number: ',msgnum);
- writeln(t,'Date: ',date);
- writeln(t,'Time: ',time);
- writeln(t,'From: ',msgfrom);
- writeln(t,'To: ',msgto);
- writeln(t,'Subj: ',msgsubj);
- writeln(t,'Conf: ',confnum);
- writeln(t,'---------------------------------');
- end; { with }
- end; { writetexthdr }
-
- begin
-
- if paramcount < 2 then
- begin
- writeln('MYRDR v0.1');
- writeln('Copyright 1993 by Brian Pape.');
- writeln('usage:');
- writeln(' MYRDR MESSAGES.DAT OUTFILE.TXT');
- writeln('where MESSAGES.DAT is the name of the unpacked data file, and');
- writeln('OUTFILE.TXT is the name of the text file to direct output to.');
- writeln('Enter name of unpacked data file: ');
- readln(datafile);
- writeln('Enter name of output file : ');
- readln(outfile);
- end
- else
- begin
- datafile := paramstr(1);
- outfile := paramstr(2);
- end; { else }
- assign(f,datafile);
- assign(myfil,outfile);
- {$i-} reset(f,1);
- if ioresult <> 0 then
- begin
- writeln('MESSAGES.DAT file not found.');
- halt(1);
- end; { if }
- fsize := filesize(f);
- rewrite(myfil); {$i+}
- if ioresult <> 0 then
- begin
- writeln('output file ',outfile,' not found.');
- halt(1);
- end; { if }
- getmem(tbuf,tbufsize);
- settextbuf(myfil, tbuf^, tbufsize);
- writeln;
- s := '';
- writeln;
- write('READ %'#8#8#8#8);
-
- { read the .QWK file header (c) by Sparkware... first }
- blockread(f,block,sizeof(block),size);
- pos := 1;
- blockread(f,buf,sizeof(buf),size);
- inc(numread,size);
- write(trunc(numread/fsize*100):3,#8#8#8);
- done := size = 0;
- while not done do begin
-
- { get the next message header and decode it }
- rawhdr := @buf[pos];
- inc(pos,128);
- convhdr(rawhdr^,prochdr);
- writetexthdr(myfil,prochdr);
-
- j := 0;
-
- msgsize := pos + 128*pred(prochdr.numblks);
- while (pos < msgsize) and not done do
- begin
- if pos>size then
- begin
-
- { reset msgsize so that we still have the same number of bytes
- to go }
- msgsize := msgsize-pos+1;
- pos := 1;
- blockread(f,buf,sizeof(buf),size);
- inc(numread,size);
- write(trunc(numread/fsize*100):3,#8#8#8);
- done := size=0;
- if done then continue;
- end; { if }
- if buf[pos] <> #227 then
- begin
- inc(j);
- s[j] := buf[pos];
- end { if }
- else
- begin
- s[0] := chr(j);
- j := 0;
- writeln(myfil,s);
- end; { else }
- inc(pos);
- end; { while }
-
- { in case pos > size, read some more data }
- if pos>size then
- begin
- pos := 1;
- blockread(f,buf,sizeof(buf),size);
- inc(numread,size);
- write(trunc(numread/fsize*100):3,#8#8#8);
- if (size=0) then done := true;
- end; { if }
-
- end; { if not done }
- end; { while }
- writeln;
- writeln('Done writing files.');
- close(f);
- close(myfil);
- freemem(tbuf, tbufsize);
- end. { myrdr }